
//50M   20ns     1ms = 1000us 1us = 1000ns    

module main(
		
		input					clk_50M,					//系统时钟
		input					rst,				  		//复位信号
		
		//蓝牙串口
		input					blt_rx,		//读取		P1
		output				blt_wx,		//接收		N2
		
		//an430
		output				lcdclk_9M,				//an430时钟
		output				lcd_de,					//an430使能信号
		output				lcd_vsync,				//场同步信号(垂直)
		output				lcd_hsync,				//行同步信号(水平)
		output[23:0]		lcd_data,					//an430显示数据 rgb565 
		
		//sdram
		output				sdram_clk,		//时钟端口
		output				sdram_cke,		//Clock enable
		output				sdram_cs,		//cmd
		output				sdram_cas,		//cmd
		output				sdram_ras,		//cmd
		output				sdram_we,		//cmd
		output[1:0]			sdram_dqm,		//Input/output mask
		output[1:0]			sdram_bank,    //块端口
		output[12:0]		sdram_addr,		//地址端口
		inout[15:0]			sdram_dq,		//数据端口		
	
		//ov5640
		inout					cmos_scl,
		inout					cmos_sda,
		input					cmos_vsync,
		input					cmos_href,
		input					cmos_pclk,
		output				cmos_xclk,
		input[7:0]			cmos_db,
		output				cmos_rst_n,
		output				cmos_pwdn
);
	
//时钟--------------------------------------------	
wire 			clk_9M;
wire			clk_100M;
wire			clk_24M;


//assign cmos_xclk = clk_24M;   //ov5640外部输入的时钟
pll_9M pll_9M_m0(
	.inclk0(clk_50M),
	.c0(clk_9M),
	.c1(cmos_xclk)
);

pll_100M pll_100M_m0(
	.inclk0(clk_50M),
	.c0(clk_100M));
	
//-------------------------------------------------------------



wire							initial_en;		//初始化完成


power_on_delay	power_on_delay_m0(
	.clk_50M                   	(clk_50M                  ),
	.reset_n                  		(rst                      ),	
	.camera_rstn               	(cmos_rst_n               ),
	.camera_pwnd                	(cmos_pwdn                ),
	.initial_en                 	(initial_en               )		
);

wire							reg_conf_done;   //ov5640配置完成
reg_config 	reg_config_m0(     
		 .clk_24M						(cmos_xclk			),
		 .camera_rstn					(cmos_rst_n			),
		 .initial_en					(initial_en			),					
		 .reg_conf_done				(reg_conf_done		),
		 .i2c_sclk						(cmos_scl			),
		 .i2c_sdat						(cmos_sda			)	
);

wire[15:0]	 	cmos_16db;
wire				data_valid;
	

ov5640_8_16bit ov5640_8_16bit_m0( 
	.pclk									(cmos_pclk			),				//ov5640数据输出时钟
	.rst									(rst					),				//复位
	.href									(cmos_href			),				//场有效，高电平有效
	.vref									(cmos_vsync			),
	.cmos_db								(cmos_db				),				//ov5640输入的数据
	
	.cmos_16db							(cmos_16db			),				//将ov5640整合为16bit的数据输出
	.data_valid							(data_valid			)				//数据是否有效		
);



	

//lcd------------------------------
wire			lcd_data_req;	//LCD数据有效
reg[15:0]	lcd_data_in;
lcd_drive lcd_drive_m0(
		.clk_50M				(clk_50M			),
		.clk_9M				(clk_9M			),		//9M时钟
		.rst					(rst				),		//复位信号
		
		//an430
		.lcdclk_9M			(lcdclk_9M		),		//an430时钟
		.lcd_de				(lcd_de			),		//an430使能信号
		.lcd_vsync			(lcd_vsync		),		//场同步信号(垂直)
		.lcd_hsync			(lcd_hsync		),		//行同步信号(水平)
		.lcd_data			(lcd_data		),		//an430显示数据 rgb565 
		
		
		.data_req			(lcd_data_req	),
		.data_in				(lcd_data_in	),
		.mode					(mode				)
);

//------------------------------------------

reg			read_req;
reg			write_req;

wire[15:0]	sdram_read_data;
wire[15:0]	sdram_write_data;

assign sdram_write_data = {cmos_16db[4:0],cmos_16db[10:5],cmos_16db[15:11]};


always@(posedge clk_9M or negedge rst)
begin
	if(rst == 1'b0)
		read_req <= 1'b0;
	else if(lcd_data_req == 1'b1)
		read_req <= 1'b1;
	else
		read_req <= 1'b0;
end

always@(posedge clk_9M or negedge rst)
begin
	if(rst == 1'b0)
		lcd_data_in <= 'd0;
	else if(lcd_data_req == 1'b1)
		lcd_data_in <= sdram_read_data;
end


reg[15:0]	mode;
reg[15:0] mode_reg;
wire[7:0] blue_data;
wire blue_ack;

reg[1:0]	mode_ack_cnt;

always@(posedge clk_50M or negedge rst)
begin
	if(rst == 1'b0)
		mode_reg = 'd0;
	else if(blue_ack == 1'b1)
		mode_reg = {mode_reg[7:0],blue_data};
	else
		mode_reg = mode_reg;
end


always@(posedge clk_50M or negedge rst)
begin
	if(rst == 1'b0)
		mode_ack_cnt <= 'd0;
	else if(blue_ack == 1'b1)
		mode_ack_cnt <= mode_ack_cnt + 1'b1;
	else
		mode_ack_cnt <= mode_ack_cnt;
end

always@(negedge clk_50M or negedge rst)
begin
	if(rst == 1'b0)
		mode <= 'd0;
	else if(mode_ack_cnt == 2'b00 || mode_ack_cnt == 2'b10)
		mode <= mode_reg;
	else
		mode <= mode;
end



Blt_Uart_Read Blt_Uart_Read_V1(

	.clk(clk_50M),
	.rst(rst),
	
	

	.ack(blue_ack),			//应答
	.data_out(blue_data),		//读到的数据
	.blt_rx(blt_rx)
	
);




sdram_fifo sdram_fifo_m0(
	.clk_50M				(cmos_pclk	    	),
	.clk_100M			(clk_100M			),
	.clk_9M				(~clk_9M				),
	.rst					(rst					),
	
	//read
	.read_req			(read_req			),
	.read_data			(sdram_read_data	),
	
	
	//write
	.write_req			(data_valid			),
	.write_data			(sdram_write_data	),
	
	
	
	
	//SDRAM
	.sdram_clk			(sdram_clk			),
	.sdram_cke			(sdram_cke			),
	.sdram_cs_n			(sdram_cs			),
	.sdram_cas_n		(sdram_cas			),
	.sdram_ras_n		(sdram_ras			),
	.sdram_we_n			(sdram_we			),
	.sdram_bank			(sdram_bank			),
	.sdram_addr			(sdram_addr			),
	.sdram_dqm			(sdram_dqm			),
	.sdram_dq			(sdram_dq			),
	.cmos_vsync			(cmos_vsync			),
	.cmos_href			(cmos_href			),
	.mode					(mode					)
);

endmodule 